<template>
  <a-card :bordered="false">
    <a-spin :spinning="isLoading">
      <div class="card-title">前台预订记录</div>
      <div class="table-operator">
        <!-- 搜索板块 -->
        <!-- <a-row class="row-item-search">
          <a-form class="search-form" :form="searchForm" layout="inline" @submit="handleSearch">
            <a-form-item label="预约查询">
              <a-input style="width: 342px" placeholder="请输入关键词" v-decorator="['searchValue']">
                <a-select slot="addonBefore" v-decorator="['searchType', { initialValue: 10 }]" style="width: 100px">
                  <a-select-option v-for="(item, index) in SearchTypeEnum" :key="index" :value="item.value">{{
                    item.name
                  }}</a-select-option>
                </a-select>
              </a-input>
            </a-form-item>
            <a-form-item label="支付方式">
              <a-select v-decorator="['payType', { initialValue: -1 }]">
                <a-select-option :value="-1">全部</a-select-option>
                <a-select-option v-for="(item, index) in PayTypeEnum.data" :key="index" :value="item.value">{{
                  item.name
                }}</a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="所属场地">
              <a-select v-decorator="['belongArena', { initialValue: -1 }]">
                <a-select-option :value="-1">全部</a-select-option>
                <a-select-option :value="0">一号场</a-select-option>
                <a-select-option :value="1">测试场地</a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="下单时间">
              <a-range-picker format="YYYY-MM-DD" v-decorator="['betweenTime']" />
            </a-form-item>
            <a-form-item class="search-btn">
              <a-button type="primary" icon="search" html-type="submit">搜索</a-button>
            </a-form-item>
            <a-form-item class="search-btn">
              <a-button @click="handleReset">重置</a-button>
            </a-form-item>
          </a-form>
        </a-row> -->
        <!-- 操作板块 -->
        <div class="row-item-tab clearfix">
          <a-range-picker @change="onSelectDate" />
          <a-button icon="download" @click="onExport">订单导出</a-button>
        </div>
      </div>
      <!-- 列表内容 -->
      <div class="ant-table ant-table-scroll-position-left ant-table-default ant-table-bordered">
        <div class="ant-table-content">
          <div class="ant-table-body">
            <table>
              <thead class="ant-table-thead">
                <tr>
                  <th v-for="(item, index) in columns" :key="index">
                    <span class="ant-table-header-column">
                      <div>
                        <span class="ant-table-column-title">{{ item.title }}</span>
                      </div>
                    </span>
                  </th>
                </tr>
              </thead>
              <tbody class="ant-table-tbody">
                <template v-for="item in orderList.data">
                  <tr class="order-empty" :key="`order_${item.id}_1`">
                    <td colspan="9"></td>
                  </tr>
                  <tr :key="`order_${item.id}_2`">
                    <td colspan="9">
                      <span class="mr-20">ID: {{ item.id }}</span>
                      <span class="mr-20 booking-arena">{{ item.fragments[0].arena }}</span>
                      <span class="mr-20 booking-date">{{ item.start_date }}</span>
                    </td>
                  </tr>
                  <!-- 场地 -->
                  <tr
                    v-for="(fragment, fragmentIndex) in item.fragments"
                    :key="`orderGoods_${item.id}_${fragmentIndex}`"
                  >
                    <td>
                      <ArenaItem :data="fragment" />
                    </td>
                    <td>
                      <p>￥{{ fragment.price }}</p>
                    </td>
                    <td>
                      <p v-if="fragment.used === 0">未使用</p>
                      <p v-if="fragment.used === 1">已使用</p>
                    </td>

                    <template v-if="fragmentIndex === 0">
                      <td :rowspan="item.fragments.length+item.referees.length">
                        <p>￥{{ calcTotal(item) }}</p>
                      </td>
                      <td :rowspan="item.fragments.length+item.referees.length">
                        {{ item.user_id.nick_name }}
                      </td>
                      <td :rowspan="item.fragments.length+item.referees.length">
                        {{ item.user_id.mobile }}
                      </td>
                      <td :rowspan="item.fragments.length+item.referees.length">
                        <p v-if="item.pay_status === 10">未支付</p>
                        <p v-else-if="item.pay_status === 20">已付款</p>
                        <p v-else-if="item.pay_status === 30">已退款</p>
                      </td>
                      <td :rowspan="item.fragments.length+item.referees.length">
                        {{ item.create_time }}
                      </td>
                      <td :rowspan="item.fragments.length+item.referees.length">
                        <a-popconfirm
                          title="确认退款"
                          ok-text="确认"
                          cancel-text="取消"
                          @confirm="onRefund(item.order_no)"
                          @cancel="cancel"
                          v-if="item.pay_status === 20"
                        >
                          <a-button >退款</a-button>
                        </a-popconfirm>

                      </td>
                    </template>

                  </tr>
                  <!-- 裁判 -->
                  <tr
                     v-for="(referee, refereeIndex) in item.referees"
                    :key="`orderReferees_${item.id}_${refereeIndex}`"
                  >
                    <td align="center">{{referee.referee_name}}</td>
                    <td>￥{{referee.price}}</td>
                  </tr>
                </template>
              </tbody>
            </table>
          </div>
          <!-- 空状态 -->
          <a-empty v-if="!orderList.data.length" :image="simpleImage" />
        </div>
      </div>
      <!-- 分页器 -->
      <div v-if="orderList.data.length" class="pagination">
        <a-pagination :current="page" :pageSize="orderList.per_page" :total="orderList.total" @change="onChangePage" />
      </div>
    </a-spin>
  </a-card>
</template>

<script>
import { Empty } from 'ant-design-vue'
import { assignment } from '@/utils/util'
import ArenaItem from './module/ArenaItem'
import * as BookingApi from '@/api/arena/booking'
import ExcelJS from 'exceljs'
import * as FileSaver from 'file-saver'

// 表格字段
const columns = [
  {
    title: '场地/裁判',
    align: 'center',
    dataIndex: 'goods',
    scopedSlots: { customRender: 'goods' },
  },
  {
    title: '价格',
    align: 'center',
    dataIndex: 'price',
    scopedSlots: { customRender: 'price' },
  },
  {
    title: '状态',
  },
  {
    title: '总价',
    dataIndex: 'total',
  },
  {
    title: '用户',
    dataIndex: 'user',
    scopedSlots: { customRender: 'user' },
  },
  {
    title: '手机号码',
    dataIndex: 'user',
    scopedSlots: { customRender: 'user' },
  },

  {
    title: '付款状态',
    dataIndex: 'pay_status',
    scopedSlots: { customRender: 'pay_status' },
  },
  {
    title: '付款时间',
    dataIndex: 'pay_time',
    scopedSlots: { customRender: 'pay_time' },
  },
  {
    title: '操作',
  },
]

export default {
  name: 'BookList',
  components: {
    ArenaItem,
  },
  data() {
    return {
      // 当前表单元素
      bookingForm: this.$form.createForm(this),
      // 查询参数
      queryParam: {},
      // 正在加载
      isLoading: false,
      // 表格字段
      columns,
      // 当前页码
      page: 1,
      // 列表数据
      orderList: { data: [], total: 0, per_page: 10 },
      // 选择的导出日期
      exportDate: [],
    }
  },

  beforeCreate() {
    // 批量给当前实例赋值
    assignment(this, {
      simpleImage: Empty.PRESENTED_IMAGE_SIMPLE,
    })
  },
  created() {
    // 初始化页面
    this.init()
  },
  methods: {
    // 初始化页面
    init() {
      this.handleRefresh(true)
    },

    // 获取当前标签
    getDataType() {
      return this.$route.path.split('/')[3]
    },

    // 计算总价
    calcTotal(item) {
      const refereePrice = item.referees.reduce((total, referee) => {
        return total + Number(referee.price)
      },0)
      const bookingPrice = item.fragments.reduce((total, fragment) => {
        return total + Number(fragment.price)
      },0)

      return refereePrice + bookingPrice
    },

    // 获取列表数据
    getList() {
      this.isLoading = true
      BookingApi.bookingList({ page: this.page })
        .then((result) => {
          console.log('list: ', result)
          this.orderList = result.data.list
        })
        .finally(() => {
          this.isLoading = false
        })

      this.isLoading = false
    },

    /**
     * 刷新列表
     * @param Boolean bool 强制刷新到第一页
     */
    handleRefresh(bool = false) {
      bool && (this.page = 1)
      this.getList()
    },

    // 翻页事件
    onChangePage(current) {
      this.page = current
      this.handleRefresh()
    },

    onSelectDate(date, dateString) {
      this.exportDate = dateString
    },

    // 导出订单，默认导出当前页数据
    async onExport() {
      const workbook = new ExcelJS.Workbook()
      const sheet = workbook.addWorksheet('预订记录')
      sheet.columns = [
        { header: '订单号', key: 'order_no', width: 32 },
        { header: '微信交易号', key: 'transaction_id', width: 32 },
        { header: '预订日期', key: 'start_date', width: 12, outlineLevel: 1 },
        { header: '场地/裁判', key: 'arena', width: 13, outlineLevel: 1 },
        { header: '半场', key: 'arena_part', width: 10, outlineLevel: 1 },
        { header: '时段', key: 'time_fragment', width: 12, outlineLevel: 1 },
        { header: '价格', key: 'price', width: 10, outlineLevel: 1 },
        { header: '总计', key: 'total', width: 10, outlineLevel: 1 },
        { header: '用户昵称', key: 'nick_name', width: 10, outlineLevel: 1 },
        { header: '用户姓名', key: 'real_name', width: 10, outlineLevel: 1 },
        { header: '付款时间', key: 'pay_time', width: 22, outlineLevel: 1 },
      ]

      let fileName = `最近的订场记录.xlsx`
      let data = this.orderList.data
      // 有选择导出日期，则按导出日期查询后台
      if (this.hasSelectExportDate()) {
        const dateArr = this.exportDate
        fileName = `订场记录${dateArr[0]}~${dateArr[1]}`
        const result = await BookingApi.bookingListFilter({ dateArr })
        data = result.data
      }

      console.log(data)
      // 遍历所有订单
      // 已合并的行数量
      let mergedRowNum = 0
      for (let i = 0, len = data.length; i < len; i++) {
        const item = data[i]

        const fragsLen = item.fragments.length
        let total = 0
        // 遍历单个订单里的所有场次
        for (let j = 0; j < fragsLen; j++) {
          const fragment = item.fragments[j]
          total += Number(fragment.price)
          sheet.addRow({
            order_no: item.order_no,
            transaction_id: item.transaction_id,
            start_date: item.start_date,
            arena: fragment.arena,
            arena_part: fragment.arena_part,
            time_fragment: fragment.time_fragment,
            price: fragment.price,
            total: total,
            nick_name: item.user_id.nick_name,
            real_name: item.user_id.real_name,
            pay_time: item.pay_time,
          })
        }

        // 遍历单个订单里所有的裁判
        const refereeLen = item.referees?.length ?? 0
        for(let k = 0; k < refereeLen; k++) {
          const referee = item.referees[k]
          total += Number(referee.price)
          sheet.addRow({
            order_no: item.order_no,
            transaction_id: item.transaction_id,
            start_date: item.start_date,
            // 裁判名字
            arena: referee.referee_name,
            arena_part: '',
            time_fragment: '',
            price: referee.price,
            total: total,
            nick_name: item.user_id.nick_name,
            real_name: item.user_id.real_name,
            pay_time: item.pay_time,
          })
        }

        const totalRowLen = fragsLen + refereeLen
        if ( totalRowLen > 1) {
          // 当前行等于索引加1（因为索引由0开始），再加1（加上表头那一行）, 再加上已合并的行数量
          let currRow = i + 1 + 1 + mergedRowNum
          // 要合并到的行位置，加1（因为索引由0开始），再加场次数量，再加上已合并的行数量
          let mergeRow = i + 1 + fragsLen + refereeLen + mergedRowNum
          // 要合并的列
          const columns = ['A', 'B', 'H', 'I', 'J', 'K']
          columns.forEach(col => {
            this.mergeRow(sheet, currRow, mergeRow, col)
          })
          // 已合并的行数，单个订单的所有场次数量加上裁判数量，再减去本身订单占的一行
          mergedRowNum = mergedRowNum + fragsLen + refereeLen - 1
        }
      }

      const EXCEL_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'
      workbook.xlsx
        .writeBuffer()
        .then((buffer) => {
          const blob = new Blob([buffer], { type: EXCEL_TYPE })
          FileSaver.saveAs(blob, fileName)
        })
        .catch((err) => {
          console.log(err)
        })
    },

    onRefund(order_no){

      this.isLoading = true
      BookingApi.refund({ order_no: order_no })
        .then((result) => {
          this.$message.success('退款成功');
          this.handleRefresh()
        })
        .finally(() => {
          this.isLoading = false
        })

    },

    /**
     * @param sheet 表格对象
     * @param currRow 当前行位置
     * @param mergeRow 要合并到的行位置
     * @param column 列名字，如M,N
     * @param mergedRowNum 已合并的行数量
     */
    mergeRow(sheet, currRow, mergeRow, column) {
        // 将合并的最后一行的值赋给合并的第一行
        sheet.getCell(`${column}${currRow}`).value = sheet.getCell(`${column}${mergeRow}`).value
        // 合并单元格
        sheet.mergeCells(`${column}${currRow}:${column}${mergeRow}`)

        // 设置合并单元格垂直居中
        sheet.getCell(`${column}${currRow}`).style.alignment = {
          vertical: 'middle',
        }
    },

    hasSelectExportDate() {
      if (this.exportDate?.[0]) {
        return true
      }

      return false
    },
  },
}
</script>
<style lang="less" scoped>
// 分页器
.pagination {
  margin-top: 16px;
  .ant-pagination {
    float: right;
  }
}

.ant-table {
  table {
    border: none;
    border-collapse: collapse;
  }
  .ant-table-thead > tr {
    border: 1px solid #e8e8e8;
  }
  tr.order-empty {
    height: 32px;
    border: 1px solid #fff;
    td {
      padding: 0;
      border-right: none;
      border-left: none;
      background: none !important;
    }
  }
}

.ant-table-thead > tr > th {
  border-right: none;
  border-bottom: none;
  padding: 12px 12px;
  font-weight: bold;
}
.ant-table-tbody > tr > td {
  border-right: 1px solid #e8e8e8;
  border-left: 1px solid #e8e8e8;
  padding: 12px 12px;
  // text-align: center;
  .booking-arena {
    font-weight: 700;
    color: #1890ff;
  }

  .booking-date {
    font-weight: 600;
    color: #1890ff;
  }

  .status-close {
    color: #ff7875;
  }
}
</style>
